package com.kenliang.javase.concurrent.lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author KenLiang
 * @description:Lock，Condition类的使用
 *
 * 其实lock是针对condition进行加锁
 *
 * @date Created in 5:35 PM 2019/3/13.
 */
public class ConditionWaitNotifyService {

    private Lock lock =  new ReentrantLock(false);
    private Condition condition = lock.newCondition();


    public void await(){
        try {
            System.out.println(Thread.currentThread().getName()+"  await start:"+System.currentTimeMillis());
            lock.lock();
            condition.await();
            System.out.println(Thread.currentThread().getName()+"  await end:"+System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void signal(){
        try {
            System.out.println(Thread.currentThread().getName()+"  signal start:"+System.currentTimeMillis());
            lock.lock();
            condition.signal();
            System.out.println(Thread.currentThread().getName()+"  signal end:"+System.currentTimeMillis());
        }finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        //这个condition 最好还是只用与一个条件
        ConditionWaitNotifyService conditionWaitNotifyService = new ConditionWaitNotifyService();
        Thread t1 = new Thread(conditionWaitNotifyService::await);
        t1.setName("t1");
        Thread t2 = new Thread(conditionWaitNotifyService::await);
        t2.setName("t2");

        Thread t3 = new Thread(conditionWaitNotifyService::await);
        t3.setName("t3");
        Thread t4 = new Thread(conditionWaitNotifyService::await);
        t4.setName("t4");

        t1.start();
        t2.start();
        t3.start();
        t4.start();

        Thread.sleep(1000);
        conditionWaitNotifyService.signal();
        conditionWaitNotifyService.signal();
        conditionWaitNotifyService.signal();
        conditionWaitNotifyService.signal();
    }

}
